﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;

namespace News
{
    public class RssFeed
    {
       
        #region Properties
     
        private string _RssHost;   
        private string _RssChannel;
        private string _RssChannelLink;

        private Int16 _ChannelId;
        private string _ChannelName;
        private string _ChannelTitle;

        private List<RssItem>  _Items;

        public string Host
        {
            get { return _RssHost; }
            set { _RssHost = value; }
        }

        public string Chanel
        {
            get { return _RssChannel; }
            set { _RssChannel = value; }
        }

        public string ChannelLink
        {
            get { return _RssChannelLink; }
            set { _RssChannelLink = value; }
        }

        public Int16  ChannelId
        {
            get { return _ChannelId; }
            set { _ChannelId = value; }
        }

        public string  ChannelName
        {
            get { return _ChannelName; }
            set { _ChannelName = value; }
        }

        public string  ChannelTitle
        {
            get { return _ChannelTitle; }
            set { _ChannelTitle = value; }
        }
     
        public List<RssItem> Items
        {
            get { return _Items; }
            set { _Items = value; }
        }

        #endregion

        #region Constructor

        public RssFeed()
        {
            _Items = new List<RssItem>();
        }

        public RssFeed(string Host, String Chanel, String ChannelLink)
        {
            _RssHost = Host;   
            _RssChannel = Chanel;
            _RssChannelLink = ChannelLink;
            _Items = new List<RssItem>();
        }

        public RssFeed(string Host, String Chanel, String  ChannelLink, List<RssItem> Items)
        {
            _RssHost = Host;
            _RssChannel = Chanel;
            _RssChannelLink = ChannelLink;
            _Items = Items;
        }

        public RssFeed(string Host, String Chanel, String URL, Int16 ChannelId, String ChannelName, String ChannelTitle, List<RssItem> Items)
        {
            _RssHost = Host;
            _RssChannel = Chanel;
            _RssChannelLink = ChannelLink;
            _ChannelId = ChannelId;
            _ChannelName = ChannelName;
            _ChannelTitle = ChannelTitle;
            _Items = Items;

        }


        #endregion

        #region Private Method

        private static XmlNode CreateItemNode(String Value, XmlDocument XmlDoc)
        {
            XmlNode myNewsNode = XmlDoc.CreateElement("BanTin");
            myNewsNode.InnerText = Value;
            return myNewsNode;
        }

        private static void GetActiveRssFeedBySubChannel(RssFeed myRssFeed, XmlNode SubChanel, string RssNodeExpression, string TitleExpression, string DescriptionExpression, string LinkExpression, string PubDateExpression, XmlDocument myResourceDocument, String XMLResource)
        {
            Boolean Active = Convert.ToBoolean(SubChanel.Attributes["active"].Value);
            if (Active == true)
            {
                #region Load RSS Resource

                string currentRSSResource = SubChanel.Attributes["rsslink"].Value;

                XmlDocument myRssDocument = new XmlDocument();
                myRssDocument.Load(currentRSSResource);

                #endregion

                #region Loop throught RSS Item to get lastest item

                XmlNode myRssTempNode; Int32 Count = 0; Int32 curItemIndex = myRssFeed.Items.Count;
                if (myRssDocument != null)
                {
                    XmlNodeList myRssNodeList = myRssDocument.SelectNodes(RssNodeExpression);
                    XmlNodeList myXmlNodeList = SubChanel.SelectNodes("BanTin");
                    if (myRssNodeList != null)
                    {
                        string myTitle = ""; string myLink = ""; string myDescription = ""; string mypubDate = "";
                        RssItem myRssItem; Boolean exists = false;

                        #region Loop throught Rss item: if Exists --> Exit else : Add Items

                        foreach (XmlNode myNode in myRssNodeList)
                        {
                            // Link
                            myRssTempNode = myNode.SelectSingleNode(LinkExpression);
                            if (myRssTempNode != null) { myLink = myRssTempNode.InnerText.ToString(); }

                            exists = false;

                            // Checked if exists item
                            foreach (XmlNode myTempXmlNode in myXmlNodeList)
                            {
                                string mycurrlink = myTempXmlNode.InnerText.ToString();
                                if (string.Compare(myLink, mycurrlink, true) == 0)
                                {
                                    exists = true;
                                    break;
                                }
                            }
                            if (exists == false)
                            {
                                // Title
                                myRssTempNode = myNode.SelectSingleNode(TitleExpression);
                                if (myRssTempNode != null) { myTitle = myRssTempNode.InnerText.ToString(); }

                                // Description
                                myRssTempNode = myNode.SelectSingleNode(DescriptionExpression);
                                if (myRssTempNode != null) { myDescription = myRssTempNode.InnerText.ToString(); }

                                // Pubdate
                                myRssTempNode = myNode.SelectSingleNode(PubDateExpression);
                                if (myRssTempNode != null) { mypubDate = myRssTempNode.InnerText.ToString(); }

                                // Save session
                                myRssItem = new RssItem(myTitle, myLink, myDescription, mypubDate, false);
                                myRssFeed.Items.Add(myRssItem);
                                Count += 1;
                            }
                            else
                            {
                                break; // Break if exists first item
                            }
                        }

                        #endregion

                        #region Update XML resource

                        if (Count > 0)
                        {
                            Count = Count + curItemIndex - 1;
                            for (Int32 index = Count; index >= curItemIndex; index--)
                            {
                                myRssTempNode = CreateItemNode(myRssFeed.Items[index].URL, myResourceDocument);
                                SubChanel.InsertBefore(myRssTempNode, SubChanel.FirstChild);
                                if (SubChanel.ChildNodes.Count > 15)
                                {
                                    SubChanel.RemoveChild(SubChanel.LastChild);
                                }
                            }
                            myResourceDocument.Save(XMLResource);
                        }
                        #endregion
                    }
                }

                #endregion
            }
        }

        #endregion

        #region Public Method

        public static RssFeed GetRssResource(string Host, string Chanel, string ChanelURL,string RootNode, string Title, string Description, string Link, string pubDate)
        {
            RssFeed myRssFeed = new RssFeed(Host, Chanel, ChanelURL);
            try
            {
                WebRequest myRequest = WebRequest.Create(ChanelURL);
                WebResponse myResponse = myRequest.GetResponse();
                Stream myRssStream = myResponse.GetResponseStream();
                //Load a XML document
                XmlDocument myRssDoc = new XmlDocument();
                myRssDoc.Load(myRssStream);
                XmlDocument myXmlDocument = new XmlDocument();
                myXmlDocument.Load(ChanelURL);
                if (myXmlDocument != null)
                {
                    XmlNodeList myXmlNodeList = myXmlDocument.SelectNodes(RootNode);
                    string myTitle = "" ;
                    string myLink = "" ;
                    string myDescription = "";
                    string mypubDate = "";
                    XmlNode myTempNode ;
                    RssItem myRssItem ;
                    //Loop throught Rss item
                    foreach ( XmlNode myNode in myXmlNodeList)
                    {
                        myTempNode = myNode.SelectSingleNode(Title);
                        if (myTempNode != null) { myTitle = myTempNode.InnerText.ToString(); }
                        myTempNode = myNode.SelectSingleNode(Description);
                        if (myTempNode != null) { myDescription = myTempNode.InnerText.ToString();}
                        myTempNode = myNode.SelectSingleNode(Link);
                        if (myLink != null) { myDescription = myTempNode.InnerText.ToString(); }
                        myTempNode = myNode.SelectSingleNode(pubDate);
                        if (mypubDate != null) { myDescription = myTempNode.InnerText.ToString(); }
                        myRssItem = new RssItem(myTitle, myLink, myDescription, mypubDate, false);
                        myRssFeed.Items.Add(myRssItem);
                    }
                }
               return myRssFeed;
            }
            catch (Exception)
            {
               return myRssFeed;
            }
            
        }

        public static RssFeed GetActiveRssFeedItems(string Host, string Channel, string RssNodeExpression, string TitleExpression, string DescriptionExpression, string LinkExpression, string PubDateExpression, XmlDocument myResourceDocument, string XMLResource)
        {
            RssFeed myRssFeed = new RssFeed();
            try
            {
              
                #region Get all news item don't exist in XML Resource

                if (myResourceDocument != null) //Neu ton tai kenh RSS trong du lieu
                {

                    #region Load RSS Chanel Resource from XML Resource

                    XmlNode myCurrRootNode;
                    myCurrRootNode = myResourceDocument.SelectSingleNode("//" + Channel);
                    
                    #endregion

                    #region Get All news RSS Item per Child Catalog Node

                    if (myCurrRootNode != null)
                    {
                        myRssFeed.ChannelId = Convert.ToInt16(myCurrRootNode.Attributes["id"].Value);
                        myRssFeed.ChannelName = myCurrRootNode.Attributes["name"].Value;
                        myRssFeed.ChannelTitle = myCurrRootNode.Attributes["title"].Value;

                        #region Loop throught Child Catalog Node For Check new RSS Item

                        foreach (XmlNode myChildNode in myCurrRootNode)
                        {
                            GetActiveRssFeedBySubChannel(myRssFeed, myChildNode, RssNodeExpression, TitleExpression, DescriptionExpression, LinkExpression, PubDateExpression, myResourceDocument, XMLResource);
                        }

                        #endregion
                
                    }
                    
                    #endregion

                }

                #endregion
           
                return myRssFeed;
            }
            catch (Exception)
            {
                return myRssFeed;
            }

        }

        public static RssFeed GetActiveRssFeedItems(string Host, string Channel, string RssNodeExpression, string TitleExpression, string DescriptionExpression, string LinkExpression, string PubDateExpression, string XMLResource)
        {
            RssFeed myRssFeed = new RssFeed();
            try
            {
                #region Load XML Resource From Hard Disk to Get Current News Item

                XMLResource = System.Web.HttpContext.Current.Server.MapPath(XMLResource);
                XmlDocument myResourceDocument = new XmlDocument();
                myResourceDocument.Load(XMLResource);

                #endregion

                #region Get all news item don't exist in XML Resource

                if (myResourceDocument != null) //Neu ton tai kenh RSS trong du lieu
                {

                    #region Load RSS Chanel Resource from XML Resource

                    XmlNode myCurrRootNode;
                    myCurrRootNode = myResourceDocument.SelectSingleNode("//" + Channel);

                    #endregion

                    #region Get All news RSS Item per Child Catalog Node

                    if (myCurrRootNode != null)
                    {
                        myRssFeed.ChannelId = Convert.ToInt16(myCurrRootNode.Attributes["id"].Value);
                        myRssFeed.ChannelName = myCurrRootNode.Attributes["name"].Value;
                        myRssFeed.ChannelTitle = myCurrRootNode.Attributes["title"].Value;

                        #region Loop throught Child Catalog Node For Check new RSS Item

                        foreach (XmlNode myChildNode in myCurrRootNode)
                        {
                            GetActiveRssFeedBySubChannel(myRssFeed, myChildNode, RssNodeExpression, TitleExpression, DescriptionExpression, LinkExpression, PubDateExpression, myResourceDocument, XMLResource);
                        }

                        #endregion

                    }

                    #endregion

                }

                #endregion

                return myRssFeed;
            }
            catch (Exception)
            {
                return myRssFeed;
            }

        }


        public static List<RssItem> GetRssItems(string Host, string Channel, string RSSChannel, string RssNodeExpression, string TitleExpression, string DescriptionExpression, string LinkExpression, string PubDateExpression, string XMLResource, String XmlNodeExpression)
        {
            RssFeed myRssFeed = new RssFeed(Host, Channel, RSSChannel);
            try
            {
                XMLResource = System.Web.HttpContext.Current.Server.MapPath(XMLResource);
                XmlDocument myResourceDocument = new XmlDocument();
                myResourceDocument.Load(XMLResource);
                XmlDocument myRssDocument = new XmlDocument();
                myRssDocument.Load(RSSChannel);
                XmlNode myRssTempNode;
                if (myRssDocument != null && myResourceDocument != null)
                {
                    XmlNodeList myRssNodeList = myRssDocument.SelectNodes(RssNodeExpression);
                    XmlNodeList myXmlNodeList = myResourceDocument.SelectNodes("//" + XmlNodeExpression + "/BanTin");
                    if (myRssNodeList != null)
                    {
                        string myTitle = ""; string myLink = ""; string myDescription = ""; string mypubDate = "";
                        RssItem myRssItem; Boolean exists = false;

                        //Loop throught Rss item
                        foreach (XmlNode myNode in myRssNodeList)
                        {
                            // Link
                            myRssTempNode = myNode.SelectSingleNode(LinkExpression);
                            if (myRssTempNode != null) { myLink = myRssTempNode.InnerText.ToString(); }

                            exists = false;

                            // Checked if exists item
                            foreach (XmlNode myTempXmlNode in myXmlNodeList)
                            {
                                string mycurrlink = myTempXmlNode.InnerText.ToString();
                                if (string.Compare(myLink, mycurrlink, true) == 0)
                                {
                                    exists = true;
                                    break;
                                }
                            }
                            if (exists == false)
                            {
                                // Title
                                myRssTempNode = myNode.SelectSingleNode(TitleExpression);
                                if (myRssTempNode != null) { myTitle = myRssTempNode.InnerText.ToString(); }

                                // Description
                                myRssTempNode = myNode.SelectSingleNode(DescriptionExpression);
                                if (myRssTempNode != null) { myDescription = myRssTempNode.InnerText.ToString(); }

                                // Pubdate
                                myRssTempNode = myNode.SelectSingleNode(PubDateExpression);
                                if (myRssTempNode != null) { mypubDate = myRssTempNode.InnerText.ToString(); }

                                // Save session
                                myRssItem = new RssItem(myTitle, myLink, myDescription, mypubDate, false);
                                myRssFeed.Items.Add(myRssItem);
                            }
                            else
                            {
                                break; // Break if exists first item
                            }
                        }
                    }
                }
                Int32 Count = myRssFeed.Items.Count - 1;
                XmlNode myCurrXmlNode;
                myCurrXmlNode = myResourceDocument.SelectSingleNode("//" + XmlNodeExpression);
                if (myRssFeed.Items.Count > 0)
                {
                    for (Int32 index = Count; index >= 0; index--)
                    {
                        myRssTempNode = CreateItemNode(myRssFeed.Items[index].URL, myResourceDocument);
                        myCurrXmlNode.InsertBefore(myRssTempNode, myCurrXmlNode.FirstChild);
                        if (myCurrXmlNode.ChildNodes.Count > 10)
                        {
                            myCurrXmlNode.RemoveChild(myCurrXmlNode.LastChild);
                        }
                    }
                    myResourceDocument.Save(XMLResource);
                }
                return myRssFeed.Items;
            }
            catch (Exception)
            {
                return myRssFeed.Items;
            }

        }

        public static  HtmlDocument GetWebResource(String ResourceURL)
        {
            HtmlDocument MyHtmlDocument = new HtmlDocument();
            try
            {
                WebRequest myRequest = WebRequest.Create(ResourceURL);
                WebResponse myResponse = myRequest.GetResponse();
                StreamReader myHTMLStream;
                myHTMLStream = new StreamReader(myResponse.GetResponseStream());
                MyHtmlDocument.Load(myHTMLStream);
                return MyHtmlDocument;
	        }
	        catch (Exception)
	        {
                return MyHtmlDocument;

	        }
        }


        //public static RssFeed GetActiveRssFeedItems(string Host, string Channel, string RssNodeExpression, string TitleExpression, string DescriptionExpression, string LinkExpression, string PubDateExpression, string XMLResource)
        //{
        //    RssFeed myRssFeed = new RssFeed();
        //    try
        //    {
        //        #region Load XML Resource From Hard Disk to Get Current News Item

        //        XMLResource = System.Web.HttpContext.Current.Server.MapPath(XMLResource);
        //        XmlDocument myResourceDocument = new XmlDocument();
        //        myResourceDocument.Load(XMLResource);

        //        #endregion

        //        #region Get all news item don't exist in XML Resource

        //        if (myResourceDocument != null) //Neu ton tai kenh RSS trong du lieu
        //        {

        //            #region Load RSS Chanel Resource from XML Resource

        //            XmlNode myCurrRootNode;
        //            myCurrRootNode = myResourceDocument.SelectSingleNode("//" + Channel);

        //            #endregion

        //            #region Get All news RSS Item per Child Catalog Node

        //            if (myCurrRootNode != null)
        //            {
        //                myRssFeed.ChannelId = Convert.ToInt16(myCurrRootNode.Attributes["id"].Value);
        //                myRssFeed.ChannelName = myCurrRootNode.Attributes["name"].Value;
        //                myRssFeed.ChannelTitle = myCurrRootNode.Attributes["title"].Value;

        //                #region Loop throught Child Catalog Node For Check new RSS Item

        //                foreach (XmlNode myChildNode in myCurrRootNode)
        //                {
        //                    Boolean Active = Convert.ToBoolean(myChildNode.Attributes["active"].Value);
        //                    if (Active == true)
        //                    {
        //                        #region Load RSS Resource

        //                        string currentRSSResource = myChildNode.Attributes["rsslink"].Value;
        //                        myRssFeed.ChannelLink = currentRSSResource;

        //                        XmlDocument myRssDocument = new XmlDocument();
        //                        myRssDocument.Load(currentRSSResource);

        //                        #endregion

        //                        #region Loop throught RSS Item to get lastest item

        //                        XmlNode myRssTempNode; Int32 Count = 0; //Count: Count geted item
        //                        if (myRssDocument != null)
        //                        {
        //                            XmlNodeList myRssNodeList = myRssDocument.SelectNodes(RssNodeExpression);
        //                            XmlNodeList myXmlNodeList = myChildNode.SelectNodes("BanTin");
        //                            if (myRssNodeList != null)
        //                            {
        //                                string myTitle = ""; string myLink = ""; string myDescription = ""; string mypubDate = "";
        //                                RssItem myRssItem; Boolean exists = false;

        //                                #region Loop throught Rss item: if Exists --> Exit else : Add Items

        //                                foreach (XmlNode myNode in myRssNodeList)
        //                                {
        //                                    // Link
        //                                    myRssTempNode = myNode.SelectSingleNode(LinkExpression);
        //                                    if (myRssTempNode != null) { myLink = myRssTempNode.InnerText.ToString(); }

        //                                    exists = false;

        //                                    // Checked if exists item
        //                                    foreach (XmlNode myTempXmlNode in myXmlNodeList)
        //                                    {
        //                                        string mycurrlink = myTempXmlNode.InnerText.ToString();
        //                                        if (string.Compare(myLink, mycurrlink, true) == 0)
        //                                        {
        //                                            exists = true;
        //                                            break;
        //                                        }
        //                                    }
        //                                    if (exists == false)
        //                                    {
        //                                        // Title
        //                                        myRssTempNode = myNode.SelectSingleNode(TitleExpression);
        //                                        if (myRssTempNode != null) { myTitle = myRssTempNode.InnerText.ToString(); }

        //                                        // Description
        //                                        myRssTempNode = myNode.SelectSingleNode(DescriptionExpression);
        //                                        if (myRssTempNode != null) { myDescription = myRssTempNode.InnerText.ToString(); }

        //                                        // Pubdate
        //                                        myRssTempNode = myNode.SelectSingleNode(PubDateExpression);
        //                                        if (myRssTempNode != null) { mypubDate = myRssTempNode.InnerText.ToString(); }

        //                                        // Save session
        //                                        myRssItem = new RssItem(myTitle, myLink, myDescription, mypubDate, false);
        //                                        myRssFeed.Items.Add(myRssItem);
        //                                        Count += 1;
        //                                    }
        //                                    else
        //                                    {
        //                                        break; // Break if exists first item
        //                                    }
        //                                }

        //                                #endregion

        //                                #region Update XML resource
        //                                if (Count > 0)
        //                                {
        //                                    for (Int32 index = Count; index >= 0; index--)
        //                                    {
        //                                        myRssTempNode = CreateItemNode(myRssFeed.Items[index].URL, myResourceDocument);
        //                                        myChildNode.InsertBefore(myRssTempNode, myChildNode.FirstChild);
        //                                        if (myChildNode.ChildNodes.Count > 10)
        //                                        {
        //                                            myChildNode.RemoveChild(myChildNode.LastChild);
        //                                        }
        //                                    }
        //                                    myResourceDocument.Save(XMLResource);
        //                                }

        //                                #endregion

        //                            }
        //                        }

        //                        #endregion
        //                    }
        //                }

        //                #endregion

        //            }

        //            #endregion

        //        }

        //        #endregion

        //        return myRssFeed;
        //    }
        //    catch (Exception)
        //    {
        //        return myRssFeed;
        //    }

        //}

       #endregion


    }
}
